﻿using System.Text;
using System;
using System.Runtime.Serialization;

namespace OpenLightGroup.Common.ApplicationServices.EventsProxy
{
    public partial class EventLogRequest
    {
        private Exception _exception;
        private Func<string> _getApplicationDetails;

        private EventLogRequest()
        {
            
        }

        public EventLogRequest(string details)
            : this(details, null, null)
        {
            // this.ClientDetails = ClientApplicationInformation.GetDetails ( ) ;
        }

        public EventLogRequest(string details, Func<string> getApplicationDetails)
            : this(details, null, getApplicationDetails)
        {
            // this.ClientDetails = ClientApplicationInformation.GetDetails ( ) ;
        }

        public EventLogRequest(string details, Exception ex)
            : this(details, ex, null)
        {
        }

        public EventLogRequest(string details, Exception ex, Func<string> getApplicationDetails)
        {
            if (getApplicationDetails != null)
                this._getApplicationDetails = getApplicationDetails;
            else
                this._getApplicationDetails = ClientApplicationInformation.GetDetails;


            this.Exception = ex;
            
            
            this.UpdateDetails(details, ex);

        }

        [IgnoreDataMember]
        public Exception Exception
        {
            get
            {
                return this._exception;
            }
            private set
            {
                this._exception = value;

                if (value != null)
                {
                    this.ExceptionMessage = value.Message;
                    this.ExceptionStackTrace = value.StackTrace;
                    this.ExceptionType = value.GetType().ToString();
                }
                else
                {
                    this.ExceptionMessage = string.Empty;
                    this.ExceptionStackTrace = string.Empty;
                    this.ExceptionType = string.Empty;

                }
            }
        }

        private void UpdateDetails(string details, Exception ex)
        {

            var detailsBuilder = new StringBuilder();

            if (!String.IsNullOrEmpty(details))
            {
                detailsBuilder.AppendLine("Additional Details:");
                detailsBuilder.AppendLine(details);
            }

            detailsBuilder.AppendLine("Client Application Details:");
            detailsBuilder.AppendLine(_getApplicationDetails());
            
            detailsBuilder.AppendLine(ClientApplicationInformation.GetStackInformation());

            if (ex != null)
            {

                detailsBuilder.AppendLine("Client Exception Details:");

                detailsBuilder.AppendLine(String.Empty);

                detailsBuilder.AppendLine("Exception Type: " + ex.GetType().ToString());
                detailsBuilder.AppendLine("Message: " + ex.Message);
                detailsBuilder.AppendLine("Stack Trace: ");
                detailsBuilder.AppendLine(ex.StackTrace);
                
                var innerEx = ex.InnerException;

                while (innerEx != null)
                {
                    detailsBuilder.AppendLine(String.Empty);

                    detailsBuilder.AppendLine("Inner Exception: ");
                    detailsBuilder.AppendLine("Exception Type: " + innerEx.GetType().ToString());
                    detailsBuilder.AppendLine("Message: " + innerEx.Message);
                    detailsBuilder.AppendLine("Stack Trace: ");
                    detailsBuilder.AppendLine(innerEx.StackTrace);

                    innerEx = innerEx.InnerException;

                }
            }

            this.ClientDetails = detailsBuilder.ToString();
        }
    }
}